/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */

package jp.ize.ux.acts;

// {{{ imports
import jp.ize.ux.UXObject;
import jp.ize.ux.geom.UXPoint;
import jp.ize.ux.acts.Act;
import jp.ize.ux.tween.UXTween;
// }}}
// {{{ typedef ScalableType
typedef ScalableType = {
	> BasicStateType,
}
// }}}
// {{{ typedef ScaleParameter > ActParameter
typedef ScaleParameter =
{
	> ActParameter,
	// {{{ var factor : Float
	/**
	 * 拡大縮小率を指定します。
	 */
	var factor : Float;
	// }}}
}
// }}}
// {{{ typedef ResizeParameter > ActParameter
typedef ResizeParameter =
{
	> ActParameter,
	// {{{ var width : Float
	/**
	 * サイズ変更後の幅を指定します。
	 */
	var width : Float;
	// }}}
	// {{{ var height : Float
	/**
	 * サイズ変更後の高さを指定します。
	 */
	var height : Float;
	// }}}
}
// }}}
// {{{ class ScaleAct extends Act
/**
 * ScaleAct クラス.<br>
 * 
 * @author		iZE Co., Ltd.<br>
 * @version		$Id$<br>
 */
class ScaleAct extends Act
{
	// {{{ public function new()
	/**
	 * コンストラクタ
	 */
	public function new()
	{
		super();
	}
	// }}}
	// {{{ public function resize( rp:ResizeParameter, ?interp:ScalableType->ResizeParameter ) : ScalableType -> Void
	/**
	 * 対象コンポーネントの左上位置を変えずに、高さと幅を変えてサイズ変更を行うアクションです。
	 */
	public function resize( rp:ResizeParameter, ?interp:ScalableType->ResizeParameter ) : ScalableType -> Void
	{
		var me = this;
		return function( state : ScalableType ) : Void {
			var param = rp;
			if ( interp!=null ) param = interp(state);
			var c = state.target;
			var goal_w = param.width;
			var goal_h = param.height;
			var end = {w:goal_w,h:goal_h};
			var getter = function(c:UXObject):{w:Float,h:Float}{
				return {w:c.width, h:c.height};
			};
			var setter = function(c:UXObject,init:{w:Float,h:Float},end:{w:Float,h:Float},v:Float) {
				c.width  = init.w+(end.w-init.w)*v;
				c.height = init.h+(end.h-init.h)*v;
			};
			var tw = new UXTween<UXObject,{w:Float,h:Float}>(c, end, getter, setter, param.time, param.transition);
			tw.setEndTweenHandler( function(e:Dynamic){
				if ( state.subject!=null ) {
					state.subject.notify(Act.STOP);
				}
			});
			var id:String = "resize";
			if ( !me.tm.objects.exists(id) ) {
				me.tm.registObject(id,c);
			}
			me.tm.addTweenChain(id,tw);
			me.tm.start(id,false,state.target);
		};
	}
	// }}}
	// {{{ public function scale( sp:ScaleParameter, ?interp:ScalableType->ScaleParameter ) : ScalableType->Void 
	/**
	 * 対象コンポーネントの中心座標を変えずに、対象コンポーネントを拡大・縮小するアクションです。
	 * 
	 */
	public function scale( sp:ScaleParameter, ?interp:ScalableType->ScaleParameter ) : ScalableType->Void 
	{
		var me = this;
		return function( state : ScalableType ) : Void {
			var param = sp;
			if ( interp!=null ) interp(state);
			var c = state.target;
			var goal_v = param.factor;
			var end = {x:param.factor,y:param.factor};
			var getter = function(c:UXObject):{x:Float,y:Float}{
				return {x:c.scaleX,y:c.scaleY};
			};
			var setter = function(c:UXObject,init:{x:Float,y:Float},end:{x:Float,y:Float},v:Float) {
				c.scaleX = init.x+(end.x-init.x)*v;
				c.scaleY = init.y+(end.y-init.y)*v;
			};
			var tw = new UXTween<UXObject,{x:Float,y:Float}>(c, end, getter, setter, param.time, param.transition);
			tw.setEndTweenHandler( function(e:Dynamic){
				if ( state.subject!=null ) {
					state.subject.notify(Act.STOP);
				}
			});
			var id:String = "scale";
			if ( !me.tm.objects.exists(id) ) {
				me.tm.registObject(id,c);
			}
			me.tm.addTweenChain(id,tw);
			me.tm.start(id,false,state.target);
		};
	}
	// }}}
	// {{{ public function fishEye( fish_interp : ScalableType -> FishEyeParameter ) : ScalableType -> Void
	/**
	 * （未実装）マウスの動きに合わせて魚眼ズームするアクションです。
	 */
	public function fishEye( fish_interp : ScalableType -> FishEyeParameter ) : ScalableType -> Void
	{
		return function( state : ScalableType ) : Void {
			// TODO
		};
	}
	// }}}
}
// }}}
